//初始化canvas
const canvas1 = document.querySelector('#canvas1');
const canvas2 = document.querySelector('#canvas2');
canvas1.width = canvas2.width = 800 ;
canvas1.height = canvas2.height = 400 ;
const ctx1 = canvas1.getContext('2d',{ willReadFrequently: true });
const ctx2 = canvas2.getContext('2d',{ willReadFrequently: true });

const baseRect = canvas2.getBoundingClientRect(); 
let shapes = [] ;

let shapeType = 'line' ; // rect , circle , fill , rubber(line)
let color = '#000000';
let lineWidth = 1 ;

//设置描边样式 和 填充样式
function setStrokeStyle(ctx){
    ctx.lineWidth = lineWidth ;
    ctx.strokeStyle = color ;
    ctx.lineCap = 'round' ;
}
function setFillStyle(ctx){
    ctx.fillStyle = color ;
}

//根据坐标(x,y)找到对应像素的其实位置
function point2Index(x,y){
    return (canvas1.width * y + x ) * 4;
}

//从16进制的颜色中获得rgba
function rgbaFromHex(){
    let tmp = color.replace('#','');
    let r = eval('0x'+tmp.substring(0,2));
    let g = eval('0x'+tmp.substring(2,4));
    let b = eval('0x'+tmp.substring(4,6));
    return [r,g,b,255];
}


//准备事件
function removeActive(){
    document.querySelector('.active').classList.remove('active') ;
}
(function preBtnEvent(){
    document.querySelector('#lineBtn').addEventListener('click',function(){
        if(this.classList.contains('active')){
            //重复点击
            return ;
        }
        removeActive();
        this.classList.add('active') ;
        shapeType = 'line' ;
    });

    document.querySelector('#rectBtn').addEventListener('click',function(){
        if(this.classList.contains('active')){
            //重复点击
            return ;
        }
        removeActive();
        this.classList.add('active') ;
        shapeType = 'rect' ;
    });

    document.querySelector('#circleBtn').addEventListener('click',function(){
        if(this.classList.contains('active')){
            //重复点击
            return ;
        }
        removeActive();
        this.classList.add('active') ;
        shapeType = 'circle' ;
    });  

    document.querySelector('#fillBtn').addEventListener('click',function(){
        if(this.classList.contains('active')){
            //重复点击
            return ;
        }
        removeActive();
        this.classList.add('active') ;
        shapeType = 'fill' ;
    });

    document.querySelector('#boldBtn').addEventListener('change',function(){
        lineWidth = this.value ;
    });
     
    document.querySelector('#colorBtn').addEventListener('change',function(){
        color = this.value ;
    });

    document.querySelector('#saveBtn').addEventListener('click',function(){
        const url = canvas1.toDataURL();
        const a = document.createElement('a');
        a.download = '保存图片' ;
        a.href = url ;
        a.click();
    });

    document.querySelector('#rubberBtn').addEventListener('click',function(){
        if(this.classList.contains('active')){
            //重复点击
            return ;
        }
        removeActive();
        this.classList.add('active') ;
        shapeType = 'rubber' ;
    });

    document.querySelector('#clearBtn').onclick = function(){
        ctx1.clearRect(0,0,canvas1.width,canvas1.height);
        shapes = [] ;
    }
})();


//设置图形类，支持线条，矩形，圆形
class Shape{
    constructor(type,x,y,ctx){
        this.type = type ;
        this.x = x ;
        this.y = y ;
        this.ctx = ctx ;
        this.ex = x ;
        this.ey = y ;
        this.points = [{x,y}];
    }
    setEx(ex){
        this.ex = ex ;
    }
    setEy(ey){
        this.ey = ey ;
    }
    addPoint(point){
        this.points.push(point);
    }
    draw(){
        switch(this.type){
            case 'line': this.drawLine(); break ;
            case 'rect': this.drawRect();break ;
            case 'circle': this.drawCircle(); break ;
            case 'rubber' : this.clearLine() ;break ;
        }
    }
    drawLine(){
        this.ctx.save();
        this.ctx.beginPath();
        setStrokeStyle(this.ctx)
        this.points.forEach((e,i)=>{
            if(i==0){
                this.ctx.moveTo(e.x,e.y);
            }else{
                this.ctx.lineTo(e.x,e.y);
            }
        });
        this.ctx.stroke();
        this.ctx.restore();
    }

    drawRect(){
        this.ctx.save();
        this.ctx.beginPath();
        setStrokeStyle(this.ctx);
        //计算矩形绘制的起始点  小的那个点
        const x = Math.min(this.x , this.ex) ;
        const y = Math.min(this.y , this.ey) ;
        const w = Math.abs(this.x - this.ex) ;
        const h = Math.abs(this.y - this.ey);
        this.ctx.strokeRect(x,y,w,h);
        this.ctx.restore();
    }

    drawCircle(){
        this.ctx.save();
        this.ctx.beginPath();
        setStrokeStyle(this.ctx);
        //计算圆的圆心和半径
        const xr = Math.abs(this.x - this.ex) / 2 ;
        const yr = Math.abs(this.y - this.ey) / 2 ;
        const origin ={
            x : Math.min(this.x , this.ex) + xr ,
            y : Math.min(this.y , this.ey) + yr
        }
        if(xr == yr){
            //绘制圆
            this.ctx.arc(origin.x,origin.y,xr,0,Math.PI * 2);
        }else{
            this.ctx.ellipse(origin.x,origin.y,xr,yr,0,0,Math.PI*2);
        }
        this.ctx.stroke();
        this.ctx.restore();
    }

    clearLine(){
        this.ctx.save() ;
        this.ctx.beginPath();
        setStrokeStyle(this.ctx)
        this.ctx.globalCompositeOperation = 'destination-out' ;
        this.points.forEach((e,i)=>{
            if(i==0){
                this.ctx.moveTo(e.x,e.y);
            }else{
                this.ctx.lineTo(e.x,e.y);
            }
        });
        this.ctx.stroke();

    }
}

ctx2.fillRect(100,100,2,2);
//监听绘制事件 鼠标按下，移动，抬起
canvas2.onmousedown = function(e){
    let x = e.clientX - baseRect.left ;
    let y = e.clientY - baseRect.top ;
    if(shapeType == 'fill'){
        const baseImageData = ctx1.getImageData(x,y,1,1);
        const r = baseImageData.data[0];
        const g = baseImageData.data[1];
        const b = baseImageData.data[2];
        const a = baseImageData.data[3];
        const [r2,g2,b2,a2] = rgbaFromHex();
        console.log(typeof r2);
        const imageData = ctx1.getImageData(0,0,canvas1.width,canvas1.height);
        function fill(x,y){
            const stack = [[x,y]];
            while(stack.length > 0){
                const [x,y] = stack.pop();
                if(x<0 || y<0 || x>canvas1.width || y > canvas1.height){
                    continue ;
                }
                const i = (imageData.width * 4) * y + x * 4 ;
                //const i = (y * imageData.width + x) * 4
                const r1 = imageData.data[i];
                const g1 = imageData.data[i+1];
                const b1 = imageData.data[i+2];
                const a1 = imageData.data[i+3];
                if(r1 != r ||
                    g1 != g ||
                    b1 != b ||
                    a1 != a){
                    continue;
                }
                imageData.data[i] = r2 ;
                imageData.data[i+1] = g2 ;
                imageData.data[i+2] = b2 ;
                imageData.data[i+3] = a2 ;
                stack.push([x-1,y],[x+1,y],[x,y-1],[x,y+1]);
            }
            
        }
        // function fill(x,y){
            //     const stack = [[x,y]];
            //     while(stack.length > 0){
        //         const [x,y] = stack.pop();
        //         if(x<0 || y<0 || x>canvas1.width || y > canvas1.height){
        //             continue ;
        //         }
        //         let imageData = ctx1.getImageData(x,y,1,1);
        //         if(imageData.data[0] != r ||
        //             imageData.data[1] != g ||
        //             imageData.data[2] != b ||
        //             imageData.data[3] != a){
        //             continue;
        //         }
        //         imageData.data[0] = 255 ;
        //         imageData.data[1] = 0 ;
        //         imageData.data[2] = 0 ;
        //         imageData.data[3] = 255 ;
        //         ctx1.putImageData(imageData,x,y);
        //         stack.push([x-1,y],[x+1,y],[x,y-1],[x,y+1]);
        //     }
        // }
        fill(x,y);
        ctx1.putImageData(imageData,0,0);
        return ;
    }
    let shape;
    if(shapeType == 'rubber'){
        ctx1.save();
        ctx1.globalCompositeOperation = 'destination-out' ;
        ctx1.beginPath();
        setStrokeStyle(ctx1);
        shape = new Shape(shapeType,x,y,ctx1);
        ctx1.moveTo(x,y) ;
    }else{
        ctx2.save();
        ctx2.beginPath();
        setStrokeStyle(ctx2);
        shape = new Shape(shapeType,x,y,ctx2);
        ctx2.moveTo(x,y);
    }

    window.onmousemove = function(e){
        let ex = e.clientX - baseRect.left ;
        let ey = e.clientY - baseRect.top ;

        switch(shapeType){
            case 'line' :  
                shape.points.push({x:ex,y:ey});
                ctx2.lineTo(ex,ey);
                ctx2.stroke();
            break ;
            case 'rect' : 
                
            case 'circle' : 
                shape.ex = ex ;
                shape.ey = ey ;
                ctx2.clearRect(0,0,canvas2.width,canvas2.height) ;
                shape.draw();
            break ;
            case 'rubber' :
                shape.points.push({x:ex,y:ey});
                ctx1.lineTo(ex,ey);
                ctx1.stroke();
            break ;
        }


        x = ex ;
        y = ey ;
    }

    window.onmouseup = function(){
        ctx2.restore();
        ctx1.restore();
        shape.ctx = ctx1 ;
        shape.draw();
        shapes.push(shape) ;
        window.onmousemove = null ;
        window.onmouseup = null ;
        ctx2.clearRect(0,0,canvas2.width,canvas2.height) ;
    }

}
